package com.retry.task.core.task;

import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

import com.retry.task.core.constants.HeartResultEnum;
import com.retry.task.core.constants.RetryTaskURIEnum;
import com.retry.task.core.heart.HeartTickDO;
import com.retry.task.core.heart.ServerHeartHolder;
import com.retry.task.core.model.RetryTaskDTO;
import com.retry.task.core.model.base.Result;
import com.retry.task.core.utils.HttpClientUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

/**
 * @author gao.gwq
 * @version 1.0
 * @date 2022/5/1  17:14
 * @Description TODO
 */
public class RetryTaskFactory {

    private RetryTaskFactory() {

    }

    public static RetryTaskFactory getInstance() {
        return InnerClass.RETRY_TASK_SERVICE;
    }

    private static final class InnerClass {
        private static final RetryTaskFactory RETRY_TASK_SERVICE = new RetryTaskFactory();
    }

    public Result<Long> createRetryTask(RetryTaskDTO retryTaskDTO) {

        if (retryTaskDTO == null) {
            return Result.getFail("100", "retryTaskDTO is null");
        }
        if (retryTaskDTO.getToken() == null) {
            return Result.getFail("100", "token is null or empty");
        }
        if (StringUtils.isEmpty(retryTaskDTO.getTaskName())) {
            return Result.getFail("100", "taskName is null or empty");
        }
        if (StringUtils.isEmpty(retryTaskDTO.getProjectName())) {
            return Result.getFail("100", "projectName is null or empty");
        }
        Result<HeartTickDO> heartTickResult = getHeartTickDO();
        if (!heartTickResult.isSuccess()) {
            return Result.getFail(heartTickResult.getCode(), heartTickResult.getErrMsg());
        }
        String realUri = heartTickResult.getData().getServerIp() + RetryTaskURIEnum.CREATE_RETRY_TASK.getUri();
        Result createTaskReslut = HttpClientUtils.postBody(realUri, retryTaskDTO,
            Long.class);
        if (!createTaskReslut.isSuccess()) {
            return Result.getFail(createTaskReslut.getCode(), createTaskReslut.getErrMsg());
        }
        return createTaskReslut;
    }

    public Result<HeartTickDO> getHeartTickDO() {
        List<HeartTickDO> heartTickDOList = ServerHeartHolder.getServerHeartList();
        if (CollectionUtils.isEmpty(heartTickDOList)) {
            return Result.getFail("100", "server list is empty");
        }
        HeartTickDO heartTickDO = getBestServer(heartTickDOList);
        //如果没有取到有效的服务，随机取一个
        if (heartTickDO == null) {
            heartTickDO = heartTickDOList.get(0);
        }
        return Result.getSuccess(heartTickDO);
    }

    /**
     *
     * 取最近一次心跳成功的，切耗时最短的
     *
     * @return
     */
    private HeartTickDO getBestServer(List<HeartTickDO> heartTickDOList) {

        //取上次心跳成功的
        List<HeartTickDO> sucessList = heartTickDOList.stream().filter(
                heartTickDO -> heartTickDO.getResult().equals(HeartResultEnum.SUCESS.getCode()))
            .collect(Collectors.toList());
        if (CollectionUtils.isEmpty(sucessList)) {
            return null;
        }
        Comparator<HeartTickDO> costTimeCoparator = (o1, o2) -> {
            if (o1.getTimeCost() > o1.getTimeCost()) {
                return 1;
            }
            return -1;
        };
        Comparator<HeartTickDO> heartTimeComparator = (o1, o2) -> o2.getLastHeartTime().compareTo(
            o1.getLastHeartTime());
        sucessList.sort(heartTimeComparator.thenComparing(costTimeCoparator));
        return sucessList.get(0);
    }
}
